package com.nulldev.util.web.YouTubeExtractor.items;

import java.util.List;
import java.util.Stack;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.VariableAPI.util.strings.splitters.Splitters;

public class YouTubeStoryboardParser {

	public static class YouTubeStoryboard {
		private static final int MIN_WIDTH = 4;

		private final String url;
		private final int sectionCount;
		private final StoryboardSection[] sections;

		public YouTubeStoryboard(final String url, final Stack<StoryboardSection> sections) {
			this.url = url;
			this.sectionCount = sections.size();
			this.sections = sections.toArray(new StoryboardSection[sections.size()]);
		}

		public String getURL() {
			return this.url;
		}

		public int getSectionCount() {
			return this.sectionCount;
		}

		public StoryboardSection[] getSections() {
			return this.sections;
		}

		public int getBestSectionSize() {
			if (this.sectionCount == 0)
				return -1;
			int widest = 0;
			int widest_idx = -1;
			for (int i = 0; i < sections.length; i++) {
				if (widest < sections[i].width || (widest == sections[i].width && sections[widest_idx].columns < sections[i].columns)) {
					if (sections[i].columns >= MIN_WIDTH) {
						widest = sections[i].width;
						widest_idx = i;
					}
				}
			}
			return widest_idx;
		}

		public String urlFor(final StoryboardSection section) {
			if (section == null || section.signatureHash == null)
				return null;
			int index = -1;
			for (int i = 0; i < sections.length; i++) {
				if (sections[i].equals(section)) {
					index = i;
					break;
				}
			}
			if (index == -1)
				return null;
			String baseURL = this.url.replace("$L", String.valueOf(index)).replace("$N", section.imageName).replace("$M", String.valueOf(0));
			if (baseURL.contains("?")) {
				baseURL += ("&sigh=" + section.signatureHash);
			} else {
				baseURL += ("?sigh=" + section.signatureHash);
			}
			return baseURL;
		}

		@Override
		public String toString() {
			return "YouTubeStoryboard[hash=" + MathUtil.toHex(super.hashCode()) + ",sections=" + this.sections + "]";
		}

		public StoryboardSection section(final int section) {
			if (section < 0 || section >= this.sectionCount)
				return null;
			return this.sections[section];
		}
	}

	public static class StoryboardSection {
		public final String quality, imageName, signatureHash;
		public final int width, height, columns, rows, duration;

		public StoryboardSection(final String quality, final String imageName, final String signatureHash, final int width, final int height, final int columns,
				final int rows, final int duration) {
			this.quality = quality;
			this.imageName = imageName;
			this.signatureHash = signatureHash;
			this.width = width;
			this.height = height;
			this.columns = columns;
			this.rows = rows;
			this.duration = duration;
		}

		public int duration() {
			return this.duration / this.columns / this.rows;
		}

		public int thumbnailCount() {
			return (int) Math.ceil(this.duration / this.duration / this.columns / this.rows);
		}
	}

	public static YouTubeStoryboard parse(final String rawURL) {
		final List<String> sections = ArrayUtils.toArrayList(Splitters.splitString(rawURL, "|"));
		final String baseURL = sections.remove(0);
		final Stack<StoryboardSection> secs = new Stack<StoryboardSection>();
		for (final String section : sections) {
			final String[] data = Splitters.splitString(section, "#");
			final String width = data[0];
			final String height = data[1];
			final String quality = data[2];
			final String columns = data[3];
			final String rows = data[4];
			final String duration = data[5];
			final String imageName = data[6];
			final String signatureHash = data[7];
			secs.add(new StoryboardSection(quality, imageName, signatureHash, Integer.parseInt(width), Integer.parseInt(height), Integer.parseInt(columns),
					Integer.parseInt(rows), Integer.parseInt(duration)));
		}
		return new YouTubeStoryboard(baseURL, secs);
	}

	public static void main(String[] args) {
		final YouTubeStoryboard sb = parse(
				"https://i.ytimg.com/sb/LU9BXg39liM/storyboard3_L$L/$N.jpg?sqp=-oaymwENSDfyq4qpAwVwAcABAaLzl_8DBgi0zITwBQ==|48#27#100#10#10#0#default#rs$AOn4CLDpg2QsoC4NxqXgmeMjgYedU6ExmQ|80#45#134#10#10#2000#M$M#rs$AOn4CLAZ4OOE-1FiexcDv3y3L7CnvGoMow|160#90#134#5#5#2000#M$M#rs$AOn4CLCKnUUY6CtS4Nobl_sKggvrKWqaow");
		JVM.println("url: " + sb.urlFor(sb.sections[sb.getBestSectionSize()]));
	}
}
